package com.wangyh.edit.prettyedit.txt;

import com.vladsch.flexmark.html.HtmlRenderer;
import com.vladsch.flexmark.parser.Parser;
import com.vladsch.flexmark.util.data.MutableDataSet;
import com.wangyh.edit.prettyedit.constant.EditConstant;
import com.wangyh.edit.prettyedit.mainframe.MainFrameView;
import com.wangyh.edit.prettyedit.pages.IPageService;
import com.wangyh.edit.prettyedit.util.PreferencesUtils;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Bounds;
import javafx.geometry.Point2D;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.control.*;
import javafx.scene.input.InputMethodEvent;
import javafx.scene.input.InputMethodRequests;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.web.HTMLEditor;
import javafx.scene.web.WebView;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import org.fxmisc.flowless.VirtualizedScrollPane;
import org.fxmisc.richtext.CodeArea;
import org.fxmisc.richtext.LineNumberFactory;

import java.io.*;
import java.lang.reflect.Member;
import java.nio.charset.Charset;
import java.util.Optional;

/**
 * 纯文本编辑器
 * @author wangyh
 *
 */
public class TextCodePage implements IPageService {

    private CodeArea codeArea = new CodeArea();
    private MainFrameView mainFrameView ;

    public TextCodePage(MainFrameView mainFrameView) {
        this.mainFrameView = mainFrameView;
    }

    @Override
    public Node generatePageToRoot(Pane root) {
        return root;
    }

    @Override
    public Node generatePage(String[] args) {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("/views/TextEditorView.fxml"));
        //根节点
        AnchorPane anchorPane = null;
        try {
            anchorPane = loader.load();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        VirtualizedScrollPane sp = new VirtualizedScrollPane(codeArea);

        File file = new File(args[0]);

        codeArea.setInputMethodRequests(new InputMethodRequestsObject(codeArea));
        codeArea.setOnInputMethodTextChanged(e->{
            if(e.getCommitted() != null){
                codeArea.insertText(codeArea.getCaretPosition(),e.getCommitted());
            }
        });
//        codeArea.setOnKeyReleased(new EventHandler<KeyEvent>() {
        codeArea.textProperty().addListener(new ChangeListener<String>() {
            @Override
            public void changed(ObservableValue<? extends String> observableValue, String s, String t1) {
                if(s.length()>0){
                    //设置名字 , 加 *
                    Stage stage = (Stage) codeArea.getParent().getScene().getWindow();
                    stage.setTitle(EditConstant.appName + "   //-> " + file.getName() + " *");
                }

                //直接保存
                String str = codeArea.getText();
                FileWriter fw = null;
                try {
                    fw = new FileWriter(file.getAbsolutePath(), Charset.forName("utf-8"));
                    fw.write(str);
                    fw.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        });

//        codeArea.setPrefHeight(100);
//        codeArea.setPrefWidth(100);
        codeArea.setParagraphGraphicFactory(LineNumberFactory.get(codeArea));
        codeArea.getStyleClass().add("code-area");
        codeArea.getStyleClass().add("keyword-editor");
        codeArea.getStylesheets().add(this.getClass().getResource("/css/prism.css").toExternalForm());
        codeArea.getStylesheets().add(this.getClass().getResource("/css/MarkdownEditor.css").toExternalForm());

        EditConstant.textSize.addListener((observable, oldValue, newValue) -> codeArea.setStyle("-fx-font-size:"+newValue));
        String fontSizeStr = PreferencesUtils.getPreferences(EditConstant.storeConfig,"fontSize","16");
        System.out.println(fontSizeStr);
        int fontSize = Integer.parseInt(fontSizeStr);
        EditConstant.textSize.setValue(fontSize);
        codeArea.setStyle("-fx-font-size:"+fontSizeStr);

        anchorPane.getChildren().add(sp);

        //设置位置
        anchorPane.setLeftAnchor(sp, 0.0);
        anchorPane.setRightAnchor(sp, 0.0);
        anchorPane.setBottomAnchor(sp, 0.0);
        anchorPane.setTopAnchor(sp, 0.0);

        codeArea.prefWidthProperty().bind(anchorPane.widthProperty());
        codeArea.prefHeightProperty().bind(anchorPane.heightProperty());

//        Map<String, Object> namespace = loader.getNamespace();
//        ScrollPane editorTab = (ScrollPane) namespace.get("scroll");
//        editorTab.setContent(codeArea);


//        Tab tab = new Tab();
//        tab.setClosable(true);
//        tab.setText("ok");
//        tab.setClosable(true);
//        tab.setContent(new VirtualizedScrollPane<>(codeArea));
//        Map<String, Object> namespace = loader.getNamespace();
//        TabPane editorTab = (TabPane) namespace.get("editorTab");
//        editorTab.getTabs().add(tab);
        loadFileData(file);

        //处理菜单事件
        generateMenu();
        return anchorPane;
    }

    public void loadFileData(File file){
        StringBuilder result = new StringBuilder();
        try{
            BufferedReader br = new BufferedReader(new FileReader(file, Charset.forName("utf-8")));//构造一个BufferedReader类来读取文件
            String s = null;
            while((s = br.readLine())!=null){//使用readLine方法，一次读一行
                result.append(s + System.lineSeparator());
            }
            br.close();
        }catch(Exception e){
            e.printStackTrace();
        }

        codeArea.replaceText(result.toString());
    }

    /**
     * 如果inputRequest为null，那么MAC系统将会出现无法输入中文的问题。
     */
    private static class InputMethodRequestsObject implements InputMethodRequests {

        private CodeArea area;

        InputMethodRequestsObject(CodeArea area){
            this.area = area;
        }

        @Override
        public Point2D getTextLocation(int offset) {
            Optional<Bounds> bounds = area.getCaretBounds();
            if (bounds.isPresent()){
                Bounds pos = bounds.get();
                return new Point2D(pos.getMinX(),pos.getMinY());
            }
            return new Point2D(0,0);
        }

        @Override
        public int getLocationOffset(int x, int y) {
            return 0;
        }

        @Override
        public void cancelLatestCommittedText() {

        }

        @Override
        public String getSelectedText() {
            return area.getSelectedText();
        }
    }


    private void generateMenu(){
        //获取菜单
        MenuBar menuBar = (MenuBar) mainFrameView.getSceneRoot().getTop();
        Menu menu = menuBar.getMenus().get(1);
        MenuItem saveMenu = menu.getItems().get(0);
        saveMenu.setDisable(false);

        saveMenu.setOnAction(
                new EventHandler<ActionEvent>() {
                    public void handle(ActionEvent event) {
                        //保存
                        BorderPane borderPane = (BorderPane) menuBar.getScene().getRoot();
                        TreeView<File> treeView = (TreeView) borderPane.getLeft();
                        TreeItem<File> selectedItem = treeView.getSelectionModel().getSelectedItem();
                        if(selectedItem!=null && selectedItem.getValue().getName().endsWith("txt")){
                            System.out.println(selectedItem.getValue().getName());
                            System.out.println(selectedItem.getValue().getAbsolutePath());

                            Node node = borderPane.getCenter();
                            System.out.println(node);
                            if(node instanceof AnchorPane){
                                VirtualizedScrollPane sp = (VirtualizedScrollPane) ((AnchorPane) node).getChildren().get(0);
                                CodeArea codeArea = (CodeArea) sp.getContent();
                                String str = codeArea.getText();

                                FileWriter fw = null;
                                try {
                                    fw = new FileWriter(selectedItem.getValue().getAbsolutePath(), Charset.forName("utf-8"));
                                    fw.write(str);
                                    fw.close();
                                } catch (IOException e) {
                                    throw new RuntimeException(e);
                                }
                            }else{
                                Alert alert = new Alert(Alert.AlertType.INFORMATION);
                                alert.setContentText("当前无编辑的文档，请编辑后进行保存！");
                                alert.setTitle("保存失败！");
                                alert.setHeaderText("保存失败！");
                                alert.show();
                            }

                            //设置名字 , 去掉 *
                            Stage stage = (Stage) menuBar.getScene().getWindow();
                            stage.setTitle(EditConstant.appName + "   //-> " + selectedItem.getValue().getName());
                        }else{
                            Alert alert = new Alert(Alert.AlertType.INFORMATION);
                            alert.setContentText("当前无编辑的文档，请编辑后进行保存！");
                            alert.setTitle("保存失败！");
                            alert.setHeaderText("保存失败！");
                            alert.show();
                        }

                    }
                }
        );

        //另存为txt
        MenuItem menuItem41 = menu.getItems().get(1);
        menuItem41.setDisable(false);
        menuItem41.setOnAction(
                new EventHandler<ActionEvent>() {
                    public void handle(ActionEvent event) {
                        FileChooser fileChooser = new FileChooser();
                        fileChooser.setTitle("另存为txt");
                        fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("txt", "*.txt"));
                        File file = fileChooser.showSaveDialog(new Stage());
                        if (file != null) {
                            //保存
                            BorderPane borderPane = (BorderPane) menuBar.getScene().getRoot();
                            TreeView<File> treeView = (TreeView) borderPane.getLeft();
                            TreeItem<File> selectedItem = treeView.getSelectionModel().getSelectedItem();
                            if(selectedItem!=null && selectedItem.getValue().getName().endsWith("txt")){
                                System.out.println(selectedItem.getValue().getName());
                                System.out.println(selectedItem.getValue().getAbsolutePath());

                                Node node = borderPane.getCenter();
                                System.out.println(node);
                                if(node instanceof AnchorPane){
                                    VirtualizedScrollPane sp = (VirtualizedScrollPane) ((AnchorPane) node).getChildren().get(0);
                                    CodeArea codeArea = (CodeArea) sp.getContent();
                                    String str = codeArea.getText();

                                    FileWriter fw = null;
                                    try {
                                        fw = new FileWriter(file, Charset.forName("utf-8"));
                                        fw.write(str);
                                        fw.close();
                                    } catch (IOException e) {
                                        throw new RuntimeException(e);
                                    }
                                }else{
                                    Alert alert = new Alert(Alert.AlertType.INFORMATION);
                                    alert.setContentText("当前无编辑的文档，请编辑后进行另存！");
                                    alert.setTitle("保存失败！");
                                    alert.setHeaderText("保存失败！");
                                    alert.show();
                                }
                            }else{
                                Alert alert = new Alert(Alert.AlertType.INFORMATION);
                                alert.setContentText("当前无编辑的文档，请编辑后进行另存！");
                                alert.setTitle("保存失败！");
                                alert.setHeaderText("保存失败！");
                                alert.show();
                            }
                        }
                    }
                }
        );

        //保存html
        MenuItem menuItem42 = menu.getItems().get(2);
        menuItem42.setDisable(true);
        menuItem42.setOnAction(
                new EventHandler<ActionEvent>() {
                    public void handle(ActionEvent event) {
                        FileChooser fileChooser = new FileChooser();
                        fileChooser.setTitle("另存为html");
                        fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("html", "*.html"));
                        File file = fileChooser.showSaveDialog(new Stage());
                        if (file != null) {
                            //保存
                            BorderPane borderPane = (BorderPane) menuBar.getScene().getRoot();
                            TreeView<File> treeView = (TreeView) borderPane.getLeft();
                            TreeItem<File> selectedItem = treeView.getSelectionModel().getSelectedItem();
                            if (selectedItem != null && selectedItem.getValue().getName().endsWith("txt")) {
                                System.out.println(selectedItem.getValue().getName());
                                System.out.println(selectedItem.getValue().getAbsolutePath());

                                Node node = borderPane.getCenter();
                                System.out.println(node);
                                if(node instanceof AnchorPane){
                                    VirtualizedScrollPane sp = (VirtualizedScrollPane) ((AnchorPane) node).getChildren().get(0);
                                    CodeArea codeArea = (CodeArea) sp.getContent();
                                    String str = codeArea.getText();

                                    FileWriter fw = null;
                                    try {
                                        fw = new FileWriter(file, Charset.forName("utf-8"));
                                        fw.write(str);
                                        fw.close();
                                    } catch (IOException e) {
                                        throw new RuntimeException(e);
                                    }
                                } else {
                                    Alert alert = new Alert(Alert.AlertType.INFORMATION);
                                    alert.setContentText("当前无编辑的文档，请编辑后进行另存！");
                                    alert.setTitle("保存失败！");
                                    alert.setHeaderText("保存失败！");
                                    alert.show();
                                }
                            } else {
                                Alert alert = new Alert(Alert.AlertType.INFORMATION);
                                alert.setContentText("当前无编辑的文档，请编辑后进行另存！");
                                alert.setTitle("保存失败！");
                                alert.setHeaderText("保存失败！");
                                alert.show();
                            }
                        }
                    }
                }
        );

        MenuItem menuItemEx = menu.getItems().get(3);
        menuItemEx.setDisable(true);
        menuItemEx.setOnAction(
                new EventHandler<ActionEvent>() {
                    public void handle(ActionEvent event) {
                        FileChooser fileChooser = new FileChooser();
                        fileChooser.setTitle("另存为pdf");
                        fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("pdf", "*.pdf"));
                        File file = fileChooser.showSaveDialog(new Stage());
                        if (file != null) {
                            //保存
                            BorderPane borderPane = (BorderPane) menuBar.getScene().getRoot();
                            TreeView<File> treeView = (TreeView) borderPane.getLeft();
                            TreeItem<File> selectedItem = treeView.getSelectionModel().getSelectedItem();
                            if (selectedItem != null && selectedItem.getValue().getName().endsWith("txt")) {
                                System.out.println(selectedItem.getValue().getName());
                                System.out.println(selectedItem.getValue().getAbsolutePath());

                                Node node = borderPane.getCenter();
                                System.out.println(node);
                                if(node instanceof AnchorPane){
                                    VirtualizedScrollPane sp = (VirtualizedScrollPane) ((AnchorPane) node).getChildren().get(0);
                                    CodeArea codeArea = (CodeArea) sp.getContent();
                                    String str = codeArea.getText();

                                    FileWriter fw = null;
                                    try {
                                        fw = new FileWriter(file, Charset.forName("utf-8"));
                                        fw.write(str);
                                        fw.close();
                                    } catch (IOException e) {
                                        throw new RuntimeException(e);
                                    }
                                } else {
                                    Alert alert = new Alert(Alert.AlertType.INFORMATION);
                                    alert.setContentText("当前无编辑的文档，请编辑后进行另存！");
                                    alert.setTitle("保存失败！");
                                    alert.setHeaderText("保存失败！");
                                    alert.show();
                                }
                            } else {
                                Alert alert = new Alert(Alert.AlertType.INFORMATION);
                                alert.setContentText("当前无编辑的文档，请编辑后进行另存！");
                                alert.setTitle("保存失败！");
                                alert.setHeaderText("保存失败！");
                                alert.show();
                            }
                        }
                    }
                }
        );

        //编辑
        Menu editMenu = menuBar.getMenus().get(2);
        MenuItem big = editMenu.getItems().get(0);
        big.setDisable(false);

        MenuItem small = editMenu.getItems().get(1);
        small.setDisable(false);

        MenuItem re = editMenu.getItems().get(2);
        re.setDisable(false);
    }

}
